package com.atguigu.yygh.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.result.R;
import com.atguigu.yygh.common.utils.JwtHelper;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.user.utils.ConstantPropertiesUtil;
import com.atguigu.yygh.user.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 杨林
 * @create 2022-11-14 19:29 星期一
 * description:
 */
@Controller
@RequestMapping("/api/user/wx")
public class WxApiController {

    @Autowired
    private UserInfoService userInfoService;
    /**
     * 获取微信登录参数
     */
    @ResponseBody
    @GetMapping("getLoginParam")
    public R getLoginParam() throws UnsupportedEncodingException {

        //前端需要用到的参数
        //self_redirect:true,  id:"login_container",  appid: "",  scope: "",  redirect_uri: "",
        //  state: "",  style: "",  href: ""
        //封装登录所需参数
        //URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL,"UTF-8")
        Map<String,Object> map = new HashMap<>();
        map.put("self_redirect", true);
        map.put("id", "weixinLogin");
        map.put("appid", ConstantPropertiesUtil.WX_OPEN_APP_ID);
        map.put("scope", "snsapi_login");
        //微信扫码后，在微信端点击确认后的重定向接口，并携带code
        map.put("redirect_uri",URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8"));
        map.put("state", System.currentTimeMillis());
        map.put("style", "black");
        map.put("href", "");
        return R.ok().data(map);
    }

    //callback ----> return String ---->  实现页面跳转（因此不能使用@RestController）
    //回调方法
    @GetMapping("callback")
    public String callback(String code) throws Exception {
        //得到授权 临时票据 （微信扫码之后点确认，微信开放平台自动接口重定向 并且自动传递临时票据）
        System.out.println("临时票据" + code);

        //调用微信端接口 根据code(临时票据)查询当前微信用户的openid
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" + ConstantPropertiesUtil.WX_OPEN_APP_ID +
                "&secret=" + ConstantPropertiesUtil.WX_OPEN_APP_SECRET +
                "&code=" + code +
                "&grant_type=authorization_code";
        String accesstokenInfo = HttpClientUtils.get(url);
        JSONObject jsonObject = JSONObject.parseObject(accesstokenInfo);

        //得到 openid 和 access_token
        String access_token = jsonObject.getString("access_token");  //查询微信昵称时使用
        String openid = jsonObject.getString("openid");

        //根据openid从mysql数据库中查询数据
        UserInfo userInfo = userInfoService.selectWxInfoByOpenId(openid);

        if (userInfo == null){
            //4、根据 access_token 和 openid 获取微信用户昵称
            String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
                    "access_token="+access_token+
                    "&openid="+openid;
            String resultInfo = HttpClientUtils.get(userInfoUrl);
            JSONObject resultObject = JSONObject.parseObject(resultInfo);
            String nickname = (String)resultObject.get("nickname");

            //添加该微信用户
            userInfo = new UserInfo();
            userInfo.setNickName(nickname);
            userInfo.setOpenid(openid);
            userInfoService.save(userInfo);
        }

        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)){
            name = userInfo.getNickName();
            if (StringUtils.isEmpty(name)){
                name = userInfo.getPhone();
            }
        }

        String token = JwtHelper.createToken(userInfo.getId(), name);

        //跳转到前端页面 pages/weixin/callback.vue
        //手机号为空：传递openid  手机号不为空 不传递openid 前端根据手机号是否为空 判断是否需要绑定手机号
        //返回name token openid 提供给前端
        //在小窗口重定向页面 callback.vue  在callback的钩子方法中调用myheader中的logincallback方法
        return "redirect:http://localhost:3000/weixin/callback?" +
                "name=" + URLEncoder.encode(name, "utf-8") + "&" +
                "token=" + token + "&" +
                "openid=" + (StringUtils.isEmpty(userInfo.getPhone()) == true ? userInfo.getOpenid(): "");
    }
}
